home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Essentials / rTutors / part3 / rTutor.cc next >
Encoding:
C/C++ Source or Header  |  1990-05-19  |  12.4 KB  |  302 lines  |  [TEXT/pdos]

  1. /* PROGRAM R.Tutor  */
  2. /* (a home-grown tutorial for writing applications using resources */
  3. /* Part 1 - starting up & shutting down the tools from a ToolStartup */
  4. /*          list kept in a resource */
  5. /* Part 2 - add a menu bar that is kept in a resource */
  6. /* Part 3 - add the event loop so that the menus "come alive" and put up a */
  7. /*          window that is defined in the resource fork */
  8.  
  9. #include <types.h>
  10. #include <INTMATH.h>
  11. #include <MEMORY.h>
  12. #include <MISCTOOL.h>
  13. #include <LOCATOR.h>
  14. #include <DESK.H>
  15. #include <QUICKDRAW.h>
  16. #include <EVENT.h>
  17. #include <CONTROL.h>
  18. #include <WINDOW.h>    
  19. #include <MENU.h>    
  20. #include <GSOS.h>
  21. #include <Resources.h>
  22.  
  23. #define  kStartStopID    1L    /* used when starting and shutting down tools */
  24.  
  25. /*---------------------- Menus & Menu Bars ---------------------------*/
  26. #define  kMenuBarID      1L   /* resource ID of the menu bar itself */
  27.  
  28.     /* define all the menu id's */
  29. #define  kAppleMenuID   1000  /* resource ID of the Apple menu */
  30. #define  kFileMenuID    2000  /* resource ID of the File menu */
  31. #define  kEditMenuID    3000  /* resource ID of the Edit menu */
  32.  
  33.     /* now, define the menu item id's */
  34. #define   kAboutBoxID   1001  /* resource ID of the About Box menu item */ 
  35.  
  36. #define   kNewItemID    2001  /* resource ID of the New Item in File menu */
  37. #define   kOpenItemID   2002  /* resource ID of the Open item in File menu */ 
  38. #define   kCloseItemID   255  /* the "Close" item */
  39. #define   kSaveItemID   2004  /* the "Save" item */
  40. #define   kSaveAsItemID 2005  /* the "Save As..." item */
  41. #define   kRevertItemID 2006  /* the "Revert to Saved" item */
  42. #define   kPageItemID   2007  /* the "Page Setup..." item */
  43. #define   kPrintItemID  2008  /* the "Print..." item */
  44. #define   kQuitItemID   2009  /* the "Quit" item */
  45.  
  46. #define   kUndoItemID      250  /* the "Undo" item */
  47. #define   kCutItemID       251  /* the "Cut" item */
  48. #define   kCopyItemID      252  /* the "Copy" item */
  49. #define   kPasteItemID     253  /* the "Paste" item */
  50. #define   kClearItemID     254  /* the "Clear" item */
  51. #define   kSelectItemID   3001  /* the "Select All" item */
  52. #define   kShowClipItemID 3002  /* the "Show ClipBoard" item */
  53.  
  54.     /* define the resource ID's for all windows used by this app */
  55. #define myWindowID    2362L  /* window's resource ID = 2362 */
  56.  
  57. /* declare the constants for our TaskMaster event mask */
  58. #define   kMyTaskMask    0x001FFFFFL  /* this mask is for TaskMaster itself */
  59. #define   kMyEventMask    0xFFFF      /* this mask is passed to GetNextEvent */
  60.  
  61. /* declare the global variable that we'll use with TaskMaster */
  62. WmTaskRec    gMyEvent;
  63.  
  64.     
  65. /* declare all of the global variables that we'll be using */    
  66. unsigned   gMyMemID;    /* holds the ID returned by MMStartup */
  67. Ref       gToolListRef; /* the list of tools used to start and stop the tools */
  68. Boolean   gPunt;        /* TRUE if it's time to quit the app */
  69.  
  70.  
  71. /* ------------------------------------------------------------------------ */
  72. /* the following procedure is responsible for putting up the About box */
  73.  
  74. do_show_about()
  75. {
  76.     /* empty for now - just beep */
  77.     SysBeep();
  78. }
  79.  
  80.  
  81. /* ------------------------------------------------------------------------ */
  82. /* the following procedure is responsible for quitting the app */
  83.  
  84. do_quit_app()
  85. {
  86.   /* we actually just set the "quit" flag and let the real quitting happen */
  87.   /* in the main event loop.  Later, we would add code here to cope with */
  88.   /* closing all open windows, saving their contents, etc. */
  89.     
  90.     gPunt = TRUE;
  91. }
  92.  
  93.  
  94. /* ------------------------------------------------------------------------ */
  95. /* the following procedure is responsible for dealing with items picked */
  96. /* from the menus by the user */
  97.  
  98. do_menu_events()
  99. {
  100.  
  101.  unsigned int   pickedMenuID; /*ID of menu the user just picked an item from */
  102.  unsigned int   pickedItemID; /* ID of item the user just picked */
  103.  
  104.  /* the hi-word of wmTaskData is the menu ID */
  105.  pickedMenuID = HiWord(gMyEvent.wmTaskData);
  106.  
  107.  /* the lo-word of wmTaskData is the item ID */
  108.  pickedItemID = LoWord(gMyEvent.wmTaskData);
  109.     
  110.     switch(pickedItemID) 
  111.     {
  112.      case kAboutBoxID : do_show_about();    /* show the About box */
  113.                           break;
  114.      case kNewItemID    : break;            /* that's all for this item */
  115.      case kOpenItemID   : break;            /* that's all for this item */
  116.      case kCloseItemID  : break;            /* that's all for this item */
  117.      case kSaveItemID   : break;            /* that's all for this item */
  118.      case kSaveAsItemID : break;            /* that's all for this item */
  119.      case kRevertItemID : break;            /* that's all for this item */
  120.      case kPageItemID   : break;            /* that's all for this item */
  121.      case kPrintItemID  : break;            /* that's all for this item */
  122.      case kQuitItemID   : do_quit_app();    /* sets gPunt to TRUE  */
  123.                           break;
  124.      case kUndoItemID   : break;            /* that's all for this item */
  125.      case kCutItemID    : break;            /* that's all for this item */
  126.      case kCopyItemID   : break;            /* that's all for this item */
  127.      case kPasteItemID  : break;            /* that's all for this item */
  128.      case kClearItemID  : break;            /* that's all for this item */
  129.      case kSelectItemID : break;            /* that's all for this item */
  130.      case kShowClipItemID : break;          /* that's all for this item */
  131.         
  132.      default: ; /* always have a default action in case something goes wrong */
  133.  
  134.     } /* end of the "switch" statement */
  135.  
  136.     /* Turn off the highlighting on the menu the user picked the item from. */
  137.     /* Then return to the main event loop to see what we'll do next. */
  138.     HiliteMenu(FALSE,pickedMenuID);
  139. }
  140.  
  141.  
  142. /* ------------------------------------------------------------------------ */
  143. /* the following procedure installs the menu bar from a resource */
  144.  
  145. do_make_menus()
  146.    MenuBarRecHndl my_mbar_hndl;
  147.    word menu_bar_height; 
  148.   { 
  149.  
  150.    /* the next three calls are ALL required to bring the menu bar in from */
  151.    /* the resource fork AND make it the current system menu bar.  For */
  152.    /* details, see the IIGS Toolbox Reference, under NewMenuBar2  */
  153.   my_mbar_hndl = NewMenuBar2(refIsResource, kMenuBarID, nil); 
  154.   SetSysBar(my_mbar_hndl); 
  155.   SetMenuBar(nil);
  156.  
  157.   /* now, add NDA's, adjust the sizes of the menus, and draw the menu bar */
  158.   /* kAppleMenuID used to be defined as a long and had to be cast to a */
  159.   /* word here.  It's been redefined to be only a word in size, so the */
  160.   /* casting is no longer needed. */
  161.   FixAppleMenu(kAppleMenuID); /* adds NDA's */
  162.   menu_bar_height =  FixMenuBar(); /* adjust the sizes */
  163.   DrawMenuBar();  /* draw the new menu bar and enjoy! */ 
  164.   }
  165. }
  166.  
  167. /* ------------------------------------------------------------------------ */
  168. /* the following procedure is responsible for starting the tools (using the */
  169. /* list in a resource) if the SartupTools call fails, then gPunt will */
  170. /* contain "TRUE", so we can abort the app the global variable for this app's */
  171. /* memory id is acquired here as well. */
  172.  
  173. do_init_rom()
  174. {
  175.     gMyMemID = _ownerid; /* find out our memory id & save it for later */
  176.  
  177.     /* crank 'em up! - make sure that kStartStopID is defined as a long!!! */
  178.     gToolListRef = StartUpTools(gMyMemID,refIsResource,kStartStopID);
  179.     
  180.     if (_toolErr == noError)
  181.       {      /* there was no error, so the app can continue starting up */
  182.         gPunt = FALSE;
  183.       }
  184.     else
  185.       {     /* something went wrong, so set gPunt to indicate the failure */
  186.         gPunt = TRUE;
  187.       }
  188. }
  189.  
  190.  
  191. /* ------------------------------------------------------------------------ */
  192. /* the following procedure draws the contents of the window that we created */
  193. /* from the template in the resource fork.  Any time the window's content */
  194. /* region needs to be redrawn, this routine gets called.  Put a SysBeep() */
  195. /* call in here if you want to investigate when this routine gets called. */
  196. /* That will cause a beep every time this routine gets called... */
  197.  
  198. drawMyContents()
  199. {
  200.     /* since all of the contents of our window are actually controls right */
  201.     /* now, we can redraw the contents just by calling DrawControls. Later, */
  202.     /* we could add code to draw other, non-control stuff. */
  203.     
  204.     GrafPortPtr   currentGrafPortPtr; /* pointer to current Graf Port */
  205.  
  206.     currentGrafPortPtr = GetPort();  /* grab the pointer to current port */
  207.     DrawControls(currentGrafPortPtr); /* draw the controls in that port */
  208. }
  209.  
  210.  
  211. /* ------------------------------------------------------------------------ */
  212. /* the following procedure creates a window using a template that is kept */
  213. /* in the application's resource fork */
  214.  
  215. do_make_window()
  216. {
  217.     /* since we only have one window and it can't be closed, we won't */
  218.     /* bother to keep the grafPortPtr in a global.  We can always get it */
  219.     /* back by calling FrontWindow().  Later, when we add multiple windows, */
  220.     /* we'll want a better way to keep track of the grafPortPtr to each */
  221.     /* window, but for now I'd like to keep it simple. */
  222.     
  223.  GrafPortPtr    myWndwPtr;
  224.  CtlRecHndl     myCtlRecHndl;
  225.     
  226.  myWndwPtr = NewWindow2(NIL, /* use "default" title string from param block */
  227.                         NIL, /* use "default" refCon from param block */
  228.                         drawMyContents, /* procedure that draws contents */
  229.                         NIL, /* use std def proc for this window */
  230.                         refIsResource,   /* template is in a resource */
  231.                         myWindowID,       /* resource ID of our window */
  232.                         rWindParam1);    /* template is of param type 1 */
  233.  
  234.     /* According to Apple IIGS Tech Note #82 (Controlling the Control Mgr) */
  235.     /* NewWindow2 does NOT set the grafPort to the newly created grafPort */
  236.     /* so it's possible for our controls to NOT be installed correctly */
  237.     /* and for the call to trash memory. So, we avoid the problem by doing */
  238.     /* exactly waht Tech Note #82 tells us to do -> don't let NewWindow2 */
  239.     /* install our controls for us.  We do this by putting NIL in the */
  240.     /* "p1ControlList" field of the rWindParam1 record (in our Rez source) */
  241.     /* and calling NewControl2 to put the controls in the window - AFTER */
  242.     /* setting the grafPort ourselves! */
  243.  
  244.     SetPort(myWndwPtr); /* set the Graf Port to the newly created window's */
  245.     myCtlRecHndl = NewControl2(myWndwPtr,    /* window to put controls in */
  246.                                resourceToResource, /* list is in resource */
  247.                                myWindowID);  /* resource ID of control list */
  248. }
  249.  
  250. /* ------------------------------------------------------------------------ */
  251. /* the following procedure is the main event loop. It runs until gPunt is */
  252. /* set to TRUE by the user picking "Quit" from the File menu. */
  253.  
  254. do_main_event()
  255. {
  256.   word  myTaskCode;  /* used to hold the task codes returned by Task Master */
  257.  
  258.   /* tell Task Master which events it can do */
  259.   /* we're lazy, so let it handle everything possible! */
  260.   gMyEvent.wmTaskMask = kMyTaskMask;
  261.  
  262.   while(!gPunt)  /* keep calling Task Master until "Quit" has been selected */
  263.   {
  264.     myTaskCode = TaskMaster(kMyEventMask, &gMyEvent);
  265.     switch(myTaskCode) 
  266.       {
  267.         case wInGoAway:
  268.            break;
  269.         case wInSpecial:
  270.         case wInMenuBar:
  271.            do_menu_events();
  272.             break;
  273.         default:  break; /* always have a default */
  274.       }    /* end of the switch statement */        
  275.     } /* end of the "while" */
  276. } /* end of do_main_event */
  277.  
  278.  
  279. /* ------------------------------------------------------------------------ */
  280. /* the following procedure is the main application itself. */
  281. /* don't forget to add the code that will check the message center to see if */
  282. /* this app was launched by clicking on its icon or by clicking on a data */
  283. /* file created by this app.  If the data file was clicked on, then grab its */
  284. /* name out of the message center and open it instead of opening the */
  285. /* untitled window. */
  286.  
  287. main()
  288. {    
  289.     do_init_rom();    /* get my memory id, start the tools, & set gPunt */
  290.     if (gPunt == FALSE)
  291.       {
  292.         do_make_menus();  /* insert the menu bar */
  293.         do_make_window(); /* create a new window from the resource fork */
  294.         InitCursor();     /* this changes the cursor to the "normal" one. */
  295.                           /* It was left as a watch cursor when the tools */
  296.                           /* were started up. */
  297.         do_main_event();
  298.       }
  299.     ShutDownTools(refIsHandle,gToolListRef); /* shut down the tools and quit */
  300. } /* end of main program */
  301.